package com.xxx.test;

import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author hdz
 * @date 2019/03/27
 */
public class TopAppActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private static final String TAG = "TopAppActivity";

    private String mTopActivityName = getClass().getName();
    private String mTopPackageName  = "com.xxx.test";
    private boolean bRunning = false;
    private final MyHandler mHandler = new MyHandler(this);

    private ThreadPoolExecutor mThreadPool;

    private AppInfoAdapter mAdapter;
    private List<AppInfo> mAppData;
    private AppManager mAppManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_top_app);

        mAppManager = new AppManager();

        ListView listView = findViewById(R.id.app_list);
        mAppData = new LinkedList<AppInfo>();
        mAdapter = new AppInfoAdapter((LinkedList<AppInfo>) mAppData, this);
        listView.setAdapter(mAdapter);
        listView.setOnItemClickListener(this);

        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.setHomeButtonEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

        int corePoolSize    = 1;
        int maximumPoolSize = 2;

        mThreadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.AbortPolicy());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (!hasAppsUsageAccessPermission()) {
                startActivityForResult(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS), PERMISSIONS_REQUEST_APPS_USAGE_ACCESS);
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mThreadPool.shutdown();
    }


    @Override
    public void onBackPressed() {
        bRunning = false;
        finish();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.onBackPressed();
                return true;
            case R.id.clear:
                mAppData.clear();
                mAdapter.notifyDataSetInvalidated();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    private void loopGetTopApp() {
        while (bRunning) {
            AppInfo info = getTopApp(TopAppActivity.this);
            if (info == null) {
                continue;
            }
            Message msg = Message.obtain();
            msg.what = 1010;
            msg.obj = info;
            mHandler.sendMessage(msg);
            if (!bRunning) {
                break;
            }
        }
    }


    /**
     * 检测用户是否对本app开启了“Apps with usage access”权限
     *
     * @return true有权限，false没有权限
     *          Android 5.0(API 21) 以下默认返回true
     *
     *  手动打开权限(小米手机为例)：设置 -〉更多设置 -〉系统安全 -〉有权查看使用情况的应用
     */
    private boolean hasAppsUsageAccessPermission() {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
            int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), getPackageName());
            if (mode != AppOpsManager.MODE_ALLOWED) {
                return false;
            }
        }
        if (mThreadPool != null) {
            mThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    bRunning = true;
                    loopGetTopApp();
                }
            });
        }
        return true;
    }

    private static final int PERMISSIONS_REQUEST_APPS_USAGE_ACCESS = 1101;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PERMISSIONS_REQUEST_APPS_USAGE_ACCESS) {
            if (!hasAppsUsageAccessPermission()) {
                //若用户未开启权限，则引导用户开启“Apps with usage access”权限
                startActivityForResult(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS), PERMISSIONS_REQUEST_APPS_USAGE_ACCESS);
            }
        }
    }

    private AppInfo getTopApp(Context context) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
            // 获取到进程管理器
            ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses();
            if (null != tasks && tasks.size() > 0) {
                String pkgName = tasks.get(0).processName;
                return new AppInfo(pkgName, "");
            }
        } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
            if (usageStatsManager != null) {
                // 获取最近3秒之内的应用数据
                long endTime = System.currentTimeMillis();
                long beginTime = endTime - 3 * 1000;
                String topActivityName = "";
                String topPackageName = "";
                long lastTimeUsed = 0;
                UsageEvents events = usageStatsManager.queryEvents(beginTime, endTime);
                while (events.hasNextEvent()) {
                    UsageEvents.Event event = new UsageEvents.Event();
                    events.getNextEvent(event);
                    if (event.getEventType()==UsageEvents.Event.MOVE_TO_BACKGROUND || event.getEventType()==UsageEvents.Event.MOVE_TO_FOREGROUND) {
                        if (event.getTimeStamp() > lastTimeUsed) {
                            lastTimeUsed = event.getTimeStamp();
                            topPackageName = event.getPackageName();
                            topActivityName = event.getClassName();
                        }
                    }
                }
                return new AppInfo(topPackageName, topActivityName);
            }
        } else {
            // 获取到进程管理器
            ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
            //获取到当前正在运行的任务栈，//参数是想获得的个数，可以随意写
            List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
            //获取到最上面的进程
            ActivityManager.RunningTaskInfo taskInfo = tasks.get(0);
            //获取到最顶端应用程序的包名和Activity名
            String topPackageName = taskInfo.topActivity.getPackageName();
            String topActivityName = taskInfo.topActivity.getClassName();

            return new AppInfo(topPackageName, topActivityName);
        }
        return null;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        mAppManager.goAppDetailSetting(this, mAppData.get(position).getPackageName());
    }


    private class MyHandler extends Handler {
        private final WeakReference<TopAppActivity> mActivity;
        public MyHandler(TopAppActivity activity) {
            mActivity = new WeakReference<TopAppActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            TopAppActivity activity = mActivity.get();
            if (msg.what == 1010) {
                AppInfo appInfo = (AppInfo)msg.obj;
                if (appInfo == null) {
                    return;
                }
                if (TextUtils.isEmpty(appInfo.getPackageName())) {
                    return;
                }
                String tmpActName = appInfo.getActivityName();
                String tmpPkgName = appInfo.getPackageName();
                if (tmpActName.equals(activity.mTopActivityName) && tmpPkgName.equals(activity.mTopPackageName)) {
                    return;
                }
                activity.mTopActivityName = appInfo.getActivityName();
                activity.mTopPackageName = appInfo.getPackageName();
                AppInfo tmpAppInfo = activity.mAppManager.getAppInfo(TopAppActivity.this, activity.mTopPackageName);
                if (tmpAppInfo == null) {
                    return;
                }
                tmpAppInfo.setActivityName(activity.mTopActivityName);
                activity.mAppData.add(tmpAppInfo);
                activity.mAdapter.notifyDataSetInvalidated();
            }
        }
    }
}
